﻿using System;
using System.Collections;
using System.Reflection;
using System.IO;
using System.Text;
using System.Data;
using System.Data.Common;
using System.Configuration;
using Light.Framework.Model;
using Light.Utility;

namespace Light.Framework.Castle
{
    public sealed class SQLManager
    {
        private SQLManager()
        { }

        #region CreateExecuter
        public static ISQLExecuter CreateExecuter()
        {
            return new DefaultSQLExecuter();
        }

        public static ISQLExecuter CreateExecuter(bool useTransaction)
        {
            return new DefaultSQLExecuter(useTransaction);
        }

        public static ISQLExecuter CreateExecuter(bool useTransaction, IsolationLevel level)
        {
            return new DefaultSQLExecuter(useTransaction, level);
        }

        public static ISQLExecuter CreateExecuter(IDbConnection connection)
        {
            return new DefaultSQLExecuter(connection);
        }

        public static ISQLExecuter CreateExecuter(IDbConnection connection, bool useTransaction)
        {
            return new DefaultSQLExecuter(connection, useTransaction);
        }

        public static ISQLExecuter CreateExecuter(IDbConnection connection, bool useTransaction, IsolationLevel level)
        {
            return new DefaultSQLExecuter(connection, useTransaction, level);
        }
        #endregion

        #region CreateDbConnection
        public static IDbConnection CreateDbConnection(string providerName)
        {
            return CreateDbConnection(providerName, null);
        }

        public static IDbConnection CreateDbConnection(string providerName, string dbConnectionString)
        {
            if (String.IsNullOrEmpty(providerName))
                throw new ArgumentNullException("typeName");

            DbProviderFactory factory = DbProviderFactories.GetFactory(providerName);
            if (factory != null)
            {
                DbConnection conn = factory.CreateConnection();
                conn.ConnectionString = dbConnectionString;

                return conn;
            }

            throw new CustomException("无法使用指定的提供者名称 " + providerName + " 创建 IDbConnection 的实例。");
        }
        #endregion

        #region GetDbConnection
        public static IDbConnection GetDbConnection()
        {
            return GetDbConnection(null);
        }

        public static IDbConnection GetDbConnection(string name)
        {
            string providerName = null;
            string connectionString = null;

            if (!String.IsNullOrEmpty(name))
            {
                ConnectionStringSettings settings = ApplicationSetting.GetConnectionStringSettings(name);
                if (settings != null)
                {
                    providerName = settings.ProviderName;
                    connectionString = settings.ConnectionString;
                }
            }
            else
            {
                providerName = ApplicationSetting.ProviderName;
                connectionString = ApplicationSetting.ConnectionString;
            }

            if (String.IsNullOrEmpty(providerName))
                return null;
            else
                return CreateDbConnection(providerName, connectionString);
        }
        #endregion

        #region DefaultSQLExecuter
        private class DefaultSQLExecuter : SQLExecuter
        {
            public DefaultSQLExecuter()
                : base()
            {
            }

            public DefaultSQLExecuter(bool useTransaction)
                : base(useTransaction)
            {
            }

            public DefaultSQLExecuter(bool useTransaction, IsolationLevel level)
                : base(useTransaction, level)
            {
            }

            public DefaultSQLExecuter(IDbConnection connection)
                : base(connection)
            {
            }

            public DefaultSQLExecuter(IDbConnection connection, bool useTransaction)
                : base(connection, useTransaction)
            {
            }

            public DefaultSQLExecuter(IDbConnection connection, bool useTransaction, IsolationLevel level)
                : base(connection, useTransaction, level)
            {
            }
        }
        #endregion

        #region GetDatabase

        public static Database GetDatabase(IDbConnection connection)
        {
            if (connection != null)
            {
                string invariantName = connection.GetType().Namespace;

                if (invariantName.Contains("Firebird"))
                    return Database.Firebird;
                else if (invariantName.Contains("Oracle"))
                    return Database.Oracle;
                else if (invariantName.Contains("MySql"))
                    return Database.MySQL;
                else if (invariantName.Contains("SqlClient"))
                    return Database.SqlServer;
                else if (invariantName.Contains("OleDb"))
                    return Database.OleDb;
            }

            return Database.MySQL;
        }

        #endregion
    }

    public enum Database
    {
        SqlServer,
        Oracle,
        OleDb,
        Firebird,
        PgSQL,
        DB2,
        MySQL,
        SQLite
    }
}
